<?php


namespace App\Service;


use GuzzleHttp\Client;
use GuzzleHttp\Pool;

class Firebase
{

    /**
     * Sending push message to single user by Firebase Registration ID
     * @param $to
     * @param $message
     *
     * @return bool|string
     */
    public function send( $to, $message ) {

        $fields = array(
            'to'   => $to,
            'data' => $message,
        );

        return $this->sendPushNotification( $fields );
    }


    /**
     * Sending message to a topic by topic name
     * @param $to
     * @param $message
     *
     * @return bool|string
     */
    public function sendToTopic( $to, $message ) {
        $fields = array(
            'to'   => '/topics/' . $to,
            'data' => $message,
        );

        return $this->sendPushNotification( $fields );
    }


    // post 请求
    private function sendPushNotification( $fields )
    {
        // Set POST variables
        $url = 'https://fcm.googleapis.com/fcm/send';
        $client = new Client();
        $result = $client->post( $url, [
            'json'    =>
                $fields
            ,
            'headers' => [
                'Authorization' => 'key='.env('FCM_SERVER_KEY'),
                'Content-Type'  => 'application/json',
            ],
        ] );

        return json_decode( $result->getBody(), true );
    }


    /**
     * Sending push message to multiple users by firebase registration ids
     * @param $registration_ids
     * @param $message
     *
     * @return bool|string
     */
    public function sendMultiple( $registration_ids, $message ) {
        $fields = array(
            'registrationIds' => $registration_ids,
//            'to' => $registration_ids,   // 单一设备
            'data' => $message,
        );
        return $this->doThread($fields);
    }


    /**
     * 批量线程发送
     * @param $fields
     * @param $callBack
     */
    private function sendPushBatchNotification( $fields ,$callBack)
    {
        $url = 'https://fcm.googleapis.com/fcm/send';
        $header = [
            'Authorization' => 'key='.env('FCM_SERVER_KEY'),
            'Content-Type'  => 'application/json',
        ];
        $client = new Client();
        $requests = function ($total) use ($client, $fields, $url, $header) {
        //  foreach ($fields['to'] as $v) {       // 单个需要开启
//            for ($page = 1; $page <= $total; $page++) {     // 多线程个需要开启  不需要了
                $sendData = [
        //  'to' => $v,  // 这是单一设备
                    'registration_ids' => $fields['registrationIds'],   // 数组多设备
                    'data' => $fields['data'],
                ];
                yield function () use ($client, $sendData, $url, $header) {
                    return $client->postAsync($url, [
                        'headers' => $header,
                        'json' => $sendData
                    ]);
                };
//            }
//            }
        };
        $total = ceil(count($fields['registrationIds'])/10);
        //        $total = count($fields['to']);
        $pool = new Pool($client, $requests($total), [
            'concurrency' => $total,
            'fulfilled' => function($response, $index) use ($callBack){
                return $callBack($response, $index);
            },
            // 失败
            'rejected' => function($response, $index) use($callBack){
                return $callBack($response, $index);
            }
        ]);
        $promise = $pool->promise();
        $promise->wait();
    }


    /**
     * 使用回调
     * @param $fields
     * @return mixed
     */
    public function doThread($fields)
    {
        $res['result'] = [];
        $this->sendPushBatchNotification($fields, function ($response, $index) use(&$res){
            $result =  $response->getbody()->getContents();
            $res['result'][$index] = $result;

        });

        return $res;

    }




}